#include "mesh_importer_exporter.h"

mesh_importer_exporter::mesh_importer_exporter(){}

object* mesh_importer_exporter::Import(char* filename)
{
	
	importer_.Import(imported_mesh_, filename);
	cout<<"import successful"<<endl;
	Reload();
	cout<<"reload successful"<<endl;
	return &object_;
}
void mesh_importer_exporter::Reload()
{
	MyMesh::VertexIterator vi;
	int i;

	MyMesh::PerVertexAttributeHandle<int> ih = vcg::tri::Allocator<MyMesh>::AddPerVertexAttribute<int> (imported_mesh_,std::string("Index"));
	// Initialize the vetex vector
	for (vi = imported_mesh_.vert.begin(), i=0 ; vi != imported_mesh_.vert.end(); vi++, i++)
	{
		Point v[3];
		v[0] = vi->P().X();
		v[1] = vi->P().Y();
		v[2] = vi->P().Z();

		ih[vi] = i;
		object_.AddVertexWithoutConstraint(v);
	}

	// Initialize the face vector
	triangle tri;
	MyMesh::FaceIterator fi;
	MyMesh::PerVertexAttributeHandle<int> rh = vcg::tri::Allocator<MyMesh>::GetPerVertexAttribute<int>(imported_mesh_,"Index");
	MyMesh::PerFaceAttributeHandle<int> ih2 = vcg::tri::Allocator<MyMesh>::AddPerFaceAttribute<int> (imported_mesh_,std::string("Index"));
	for (fi = imported_mesh_.face.begin(), i=0; fi != imported_mesh_.face.end(); fi++, i++)
	{
		tri.alive = true;
		tri.index = i;
		tri.child_tri.clear();
		tri.pt[0] = rh[fi->V0(0)];
		tri.pt[1] = rh[fi->V1(0)];
		tri.pt[2] = rh[fi->V2(0)];
		ih2[fi] = i;
		object_.AddTriangle(tri);
	}
	MyMesh::PerFaceAttributeHandle<int> rh2 = vcg::tri::Allocator<MyMesh>::GetPerFaceAttribute<int>(imported_mesh_,"Index");
	for (fi = imported_mesh_.face.begin(), i=0; i<object_.GetTriangleSize(); fi++, i++) 
	{
		if ( fi->FFp(0) != NULL)
			object_.SetTriangleIndexVersionValue(i, 0, rh2[fi->FFp(0)]);
		else
			object_.SetTriangleIndexVersionValue(i, 0, -1);

		if ( fi->FFp(1) != NULL)
			object_.SetTriangleIndexVersionValue(i, 1, rh2[fi->FFp(1)]);
		else 
			object_.SetTriangleIndexVersionValue(i, 1, -1);

		if ( fi->FFp(2) != NULL)
			object_.SetTriangleIndexVersionValue(i, 2, rh2[fi->FFp(2)]);
		else 
			object_.SetTriangleIndexVersionValue(i, 2, -1);
	}
}
void mesh_importer_exporter::Export(char *filename)
{
	vector<tri::Allocator<MyMesh>::VertexPointer> vp;
	tri::Allocator<MyMesh>::AddVertices(exported_mesh_, object_.GetVertexSize());

	// export the vertices
	vector<pt_vertex> vtx_vector = object_.GetVertexVector();
	for (int i=0; i<object_.GetVertexSize(); i++)
	{
		exported_mesh_.vert[i].P() = vtx_vector[i].xyz;
		vp.push_back(&exported_mesh_.vert[i]);
	}

	// export the faces
	vector<tri::Allocator<MyMesh>::FacePointer> fp;
	vector<triangle>::iterator iter = object_.GetTriangleVectorPointer();
	tri::Allocator<MyMesh>::AddFaces(exported_mesh_, object_.GetTriangleSize());
	for (int i=0; i<object_.GetTriangleSize(); i++, iter++)
	{
		exported_mesh_.face[i].V0(0) = vp[iter->pt[0]];
		exported_mesh_.face[i].V1(0) = vp[iter->pt[1]];
		exported_mesh_.face[i].V2(0) = vp[iter->pt[2]];
	}

	// update the mesh structure
	tri::UpdateTopology<MyMesh>::FaceFace(exported_mesh_);
	tri::UpdateFlags<MyMesh>::FaceBorderFromFF(exported_mesh_);
	tri::UpdateNormals<MyMesh>::PerVertexNormalized(exported_mesh_);

	// export as file
	tri::io::ExporterPLY<MyMesh>::Save(exported_mesh_, filename ,(vcg::CallBackPos*) 0);

}